
package org.bridgen.lang.semantics.ast;
import java.util.*;

// Generated with JastAdd II (http://jastadd.cs.lth.se) version R20080423

public class ASTNode<T extends ASTNode> implements Cloneable, Iterable<T> {
    public void flushCache() {
    }
     @SuppressWarnings({"unchecked", "cast"})  public ASTNode<T> clone() throws CloneNotSupportedException {
        ASTNode node = (ASTNode)super.clone();
        node.in$Circle(false);
        node.is$Final(false);
    return node;
    }
     @SuppressWarnings({"unchecked", "cast"})  public ASTNode<T> copy() {
      try {
          ASTNode node = (ASTNode)clone();
          if(children != null) node.children = (ASTNode[])children.clone();
          return node;
      } catch (CloneNotSupportedException e) {
      }
      System.err.println("Error: Could not clone node of type " + getClass().getName() + "!");
      return null;
    }
     @SuppressWarnings({"unchecked", "cast"})  public ASTNode<T> fullCopy() {
        ASTNode res = (ASTNode)copy();
        for(int i = 0; i < getNumChildNoTransform(); i++) {
          ASTNode node = getChildNoTransform(i);
          if(node != null) node = node.fullCopy();
          res.setChild(node, i);
        }
        return res;
    }
    // Declared in Compilation.jrag at line 8


	// Locations form the parser
	public void setLocation(int line, int column) {
		this.line = line;
		this.column = column;
	}

    // Declared in Compilation.jrag at line 12

	public int getLine() {
		return line;
	}

    // Declared in Compilation.jrag at line 15

	public int getColumn() {
		return column;
	}

    // Declared in Compilation.jrag at line 18

	protected int line = -1;

    // Declared in Compilation.jrag at line 19

	protected int column = -1;

    // Declared in ErrorCheck.jrag at line 11

	
	// Error collection
	
	protected void error(Collection errorList, String msg) {
		errorList.add(new SemanticError(msg, getLine(), getColumn()));
	}

    // Declared in NameAnalysis.jrag at line 11


	// Methods for traversal

	public void nameAnalysis(Collection errorList) {
		for (int i = 0; i < getNumChild(); i++) {
			getChild(i).nameAnalysis(errorList); 
		}	
	}

    // Declared in PatternAnalysis.jrag at line 12

	
	public void checkPatterns(Collection errorList) {
		for (int i = 0; i < getNumChild(); i++) {
			getChild(i).checkPatterns(errorList);
		}
	}

    // Declared in PrettyPrint.jrag at line 32


	public void pp(StringBuffer buf) {
	  for (int i = 0; i < getNumChild(); i++) {
	  	getChild(i).pp(buf);
	  } 
	}

    // Declared in TypeAnalysis.jrag at line 11


	// Method for traversal

	public void typeAnalysis(Collection errorList) {
		for (int i = 0; i < getNumChild(); i++) {
			getChild(i).typeAnalysis(errorList);
		}
	}

    // Declared in TypeCodeGen.jrag at line 10


	// Indent
	protected String INDENT = "\t";

    // Declared in TypeCodeGen.jrag at line 535

	
	
	
	
	public void collectAttributeChecks(TreeSet<String> set) {
		for (int i = 0; i < getNumChild(); i++) {
			getChild(i).collectAttributeChecks(set);
		}
	}

    // Declared in ASTNode.ast at line 3
    // Declared in ASTNode.ast line 0

    public ASTNode() {
        super();


    }

    // Declared in ASTNode.ast at line 9


   static public boolean generatedWithCircularEnabled = true;

    // Declared in ASTNode.ast at line 10

   static public boolean generatedWithCacheCycle = false;

    // Declared in ASTNode.ast at line 11

   static public boolean generatedWithComponentCheck = false;

    // Declared in ASTNode.ast at line 12

  static public boolean IN_CIRCLE = false;

    // Declared in ASTNode.ast at line 13

  static public int CIRCLE_INDEX;

    // Declared in ASTNode.ast at line 14

  static public boolean CHANGE = false;

    // Declared in ASTNode.ast at line 15

  static public boolean RESET_CYCLE = false;

    // Declared in ASTNode.ast at line 16

  public static int boundariesCrossed = 0;

    // Declared in ASTNode.ast at line 43

  protected static ASTNode$State state = new ASTNode$State();

    // Declared in ASTNode.ast at line 44

  public boolean in$Circle = false;

    // Declared in ASTNode.ast at line 45

  public boolean in$Circle() { return in$Circle; }

    // Declared in ASTNode.ast at line 46

  public void in$Circle(boolean b) { in$Circle = b; }

    // Declared in ASTNode.ast at line 47

  public boolean is$Final = false;

    // Declared in ASTNode.ast at line 48

  public boolean is$Final() { return is$Final; }

    // Declared in ASTNode.ast at line 49

  public void is$Final(boolean b) { is$Final = b; }

    // Declared in ASTNode.ast at line 50

  protected static final int REWRITE_CHANGE = 1;

    // Declared in ASTNode.ast at line 51

  protected static final int REWRITE_NOCHANGE = 2;

    // Declared in ASTNode.ast at line 52

  protected static final int REWRITE_INTERRUPT = 3;

    // Declared in ASTNode.ast at line 53

  @SuppressWarnings("cast") public T getChild(int i) {
    return (T)ASTNode.getChild(this, i);
  }

    // Declared in ASTNode.ast at line 56

  public static ASTNode getChild(ASTNode that, int i) {
    ASTNode node = that.getChildNoTransform(i);
    if(node.is$Final()) return node;
    if(!node.mayHaveRewrite()) {
      node.is$Final(that.is$Final());
      return node;
    }
    if(!node.in$Circle()) {
      int rewriteState;
      int num = ASTNode.boundariesCrossed;
      do {
        ASTNode.state.push(ASTNode.REWRITE_CHANGE);
        ASTNode oldNode = node;
        oldNode.in$Circle(true);
        node = node.rewriteTo();
        if(node != oldNode)
          that.setChild(node, i);
        oldNode.in$Circle(false);
        rewriteState = state.pop();
      } while(rewriteState == ASTNode.REWRITE_CHANGE);
      if(rewriteState == ASTNode.REWRITE_NOCHANGE && that.is$Final()) {
        node.is$Final(true);
        ASTNode.boundariesCrossed = num;
      }
    }
    else if(that.is$Final() != node.is$Final()) boundariesCrossed++;
    return node;
  }

    // Declared in ASTNode.ast at line 84

  private int childIndex;

    // Declared in ASTNode.ast at line 85

  public int getIndexOfChild(ASTNode node) {
    if(node != null && node.childIndex < getNumChildNoTransform() && node == getChildNoTransform(node.childIndex))
      return node.childIndex;
    for(int i = 0; i < getNumChildNoTransform(); i++)
      if(getChildNoTransform(i) == node) {
        node.childIndex = i;
        return i;
      }
    return -1;
  }

    // Declared in ASTNode.ast at line 96


  public void addChild(T node) {
    setChild(node, getNumChildNoTransform());
  }

    // Declared in ASTNode.ast at line 99

  @SuppressWarnings("cast") public final T getChildNoTransform(int i) {
    return (T)children[i];
  }

    // Declared in ASTNode.ast at line 102

  protected ASTNode parent;

    // Declared in ASTNode.ast at line 103

  protected ASTNode[] children;

    // Declared in ASTNode.ast at line 104

  protected int numChildren;

    // Declared in ASTNode.ast at line 105

  protected int numChildren() {
    return numChildren;
  }

    // Declared in ASTNode.ast at line 108

  public int getNumChild() {
    return numChildren();
  }

    // Declared in ASTNode.ast at line 111

  public final int getNumChildNoTransform() {
    return numChildren();
  }

    // Declared in ASTNode.ast at line 114

  public void setChild(T node, int i) {
    if(children == null) {
      children = new ASTNode[i + 1];
    } else if (i >= children.length) {
      ASTNode c[] = new ASTNode[i << 1];
      System.arraycopy(children, 0, c, 0, children.length);
      children = c;
    }
    children[i] = node;
    if(i >= numChildren) numChildren = i+1;
    if(node != null) { node.setParent(this); node.childIndex = i; }
  }

    // Declared in ASTNode.ast at line 126

  public void insertChild(T node, int i) {
    if(children == null) {
      children = new ASTNode[i + 1];
      children[i] = node;
    } else {
      ASTNode c[] = new ASTNode[children.length + 1];
      System.arraycopy(children, 0, c, 0, i);
      c[i] = node;
      if(i < children.length)
        System.arraycopy(children, i, c, i+1, children.length-i);
      children = c;
    }
    numChildren++;
    if(node != null) { node.setParent(this); node.childIndex = i; }
  }

    // Declared in ASTNode.ast at line 141

  public void removeChild(int i) {
    if(children != null) {
      ASTNode child = children[i];
      if(child != null) {
        child.setParent(null);
        child.childIndex = -1;
      }
      System.arraycopy(children, i+1, children, i, children.length-i-1);
      numChildren--;
    }
  }

    // Declared in ASTNode.ast at line 152

  public ASTNode getParent() {
    if(parent != null && parent.is$Final() != is$Final()) {
      boundariesCrossed++;
    }
    return parent;
  }

    // Declared in ASTNode.ast at line 158

  public void setParent(ASTNode node) {
    parent = node;
  }

    // Declared in ASTNode.ast at line 161

    public static void reset() {
        IN_CIRCLE = false;
        CIRCLE_INDEX = 0;
        CHANGE = false;
        boundariesCrossed = 0;
        state = new ASTNode$State();
    }

    // Declared in ASTNode.ast at line 168

    public java.util.Iterator<T> iterator() {
        return new java.util.Iterator<T>() {
            private int counter = 0;
            public boolean hasNext() {
                return counter < getNumChild();
            }
            @SuppressWarnings("unchecked") public T next() {
                if(hasNext())
                    return (T)getChild(counter++);
                else
                    return null;
            }
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }

    // Declared in ASTNode.ast at line 185

  public boolean mayHaveRewrite() { return false; }

    // Declared in TypeCodeGen.jrag at line 19
    protected void collect_contributors_Grammar_nodeDecls() {
        for(int i = 0; i < getNumChild(); i++)
            getChild(i).collect_contributors_Grammar_nodeDecls();
    }

    protected void contributeTo_Grammar_Grammar_nodeDecls(Collection collection) {
    }


    // Declared in TypeCodeGen.jrag at line 25
    protected void collect_contributors_Grammar_ignoreDecls() {
        for(int i = 0; i < getNumChild(); i++)
            getChild(i).collect_contributors_Grammar_ignoreDecls();
    }

    protected void contributeTo_Grammar_Grammar_ignoreDecls(Collection collection) {
    }


    // Declared in TypeCodeGen.jrag at line 22
    protected void collect_contributors_NodeDecl_attrDecls() {
        for(int i = 0; i < getNumChild(); i++)
            getChild(i).collect_contributors_NodeDecl_attrDecls();
    }

    protected void contributeTo_NodeDecl_NodeDecl_attrDecls(Collection collection) {
    }


public ASTNode rewriteTo() {
    if(state.peek() == ASTNode.REWRITE_CHANGE) {
        state.pop();
        state.push(ASTNode.REWRITE_NOCHANGE);
    }
    return this;
}

    public String Define_String_indent(ASTNode caller, ASTNode child) {
        return getParent().Define_String_indent(this, caller);
    }
    public Grammar Define_Grammar_enclosingGrammar(ASTNode caller, ASTNode child) {
        return getParent().Define_Grammar_enclosingGrammar(this, caller);
    }
    public NodeUse Define_NodeUse_lookupVariable(ASTNode caller, ASTNode child, String name) {
        return getParent().Define_NodeUse_lookupVariable(this, caller, name);
    }
    public NodeDecl Define_NodeDecl_lookupNode(ASTNode caller, ASTNode child, String name) {
        return getParent().Define_NodeDecl_lookupNode(this, caller, name);
    }
    public RecoverDecl Define_RecoverDecl_lookupRecovery(ASTNode caller, ASTNode child, String name) {
        return getParent().Define_RecoverDecl_lookupRecovery(this, caller, name);
    }
    public BridgeDecl Define_BridgeDecl_lookupBridge(ASTNode caller, ASTNode child, String name) {
        return getParent().Define_BridgeDecl_lookupBridge(this, caller, name);
    }
}
